<script setup>
import { ref } from "vue";
import { uploadFile } from "@/utils/api/upload";
import { getFileList, delFile } from "@/utils/api/file";
import { useUserStore } from "@/store/modules/useUserStore";
import { dayjs, ElMessage } from "element-plus";
import { isEmptyObject, deepClone, removeEmptyKeys } from "@/utils/base";
import { fileTypes, fileUseTypes } from "./constants/aboutFile";
import axios from "axios";

const BASE_URL = import.meta.env.VITE_BASE_URL;
const STATIC_URL = import.meta.env.VITE_STATIC_URL;

const userToken = useUserStore().userToken;
const userId = useUserStore().userInfo.id;

// 列表数据
const loading = ref(false);
const tableData = ref([]);
const total = ref(0);
const currentPage = ref(0);
const pageSize = ref(20);
// 筛选条件
const formInline = ref({
  isPaging: 1
});

const dataInit = async () => {
  loading.value = true;

  const filter = deepClone(formInline.value);
  if (filter.file_size) {
    filter.file_size = filter.file_size * 1000000;
  }

  const res = await getFileList({ pageNum: currentPage.value, pageSize: pageSize.value, ...removeEmptyKeys(filter) });
  if (res.success) {
    tableData.value = res.data.list;
    total.value = res.data.count;
  }
  loading.value = false;
};
dataInit();

// 选择文件
const fileList = ref([]);
function showUpload(form) {
  if (form.file_type && form.use_type) {
    return true;
  } else {
    return false;
  }
}

const dialogFormVisible = ref(false);
const dialogForm = ref({});
// 添加
const handleAdd = () => {
  dialogFormVisible.value = true;
  dialogForm.value = {};
};

// 验证表单
const validateForm = (form) => {
  if (isEmptyObject(form)) {
    ElMessage.error("请填写表单");
    return false;
  }
  if (!form.file_type || !form.use_type) {
    ElMessage.error("请填写完整信息");
    return false;
  }
  return true;
};

// 提交表单
const uploaProgress = ref(0);
const progressVisible = ref(false);
const uploadSpeed = ref(0);
const nowUploadcount = ref(0);
const submitForm = async (Form) => {
  dialogFormVisible.value = false;
  if (!validateForm(Form)) {
    return;
  }

  if (fileList.value.length === 0) {
    ElMessage.error("请选择文件");
    return;
  }
  progressVisible.value = true;
  dialogForm.value.uid = userId;
  for (let i = 0; i < fileList.value.length; i++) {
    const file = fileList.value[i].raw;
    const formData = new FormData();
    formData.append("file", file);
    nowUploadcount.value = i + 1;
    try {
      const uploadRes = await uploadFile(dialogForm.value, formData, userToken, (res) => {
        uploadSpeed.value = Math.round((res.rate / 1024 / 1024) * 100) / 100;
        uploaProgress.value = Math.round(res.progress * 100);
      });
      if (uploadRes.data.success) {
        ElMessage.success(`第${i + 1}个文件上传成功`);
      } else {
        ElMessage.success(`第${i + 1}个文件上传失败`);
      }
    } catch (error) {
      console.log(error);
      ElMessage.success(`第${i + 1}个文件上传失败`);
      continue;
    }
  }
  progressVisible.value = false;
  fileList.value = [];
  resetForm();
  dataInit();
};

// 重置
const resetForm = () => {
  dialogFormVisible.value = false;
  dialogForm.value = {};
};

// 选择
const selectionIds = ref([]);
const selectionFiles = ref([]);
const handleSelectionChange = (val) => {
  selectionIds.value = val.map((e) => e.id);
  selectionFiles.value = val.map((e) => STATIC_URL + e.file_name);
};

// 删除
const handleDelete = async (ids) => {
  try {
    const res = await delFile({ ids });
    if (res.success) {
      ElMessage.success("删除成功");
      dataInit();
    } else {
      ElMessage.error("删除失败");
    }
  } catch (error) {
    console.log(error);
  }
};

// 预览
const imageVisible = ref(false);
const viewedImage = ref("");
const handlePreview = (fileName) => {
  imageVisible.value = true;
  viewedImage.value = STATIC_URL + fileName;
};

/* 下载选择的全部文件 */
const downloadAllFile = async (files) => {
  if (files.length === 0) {
    ElMessage.error("没有可下载的文件！");
    return;
  }
  for (let i = 0; i < files.length; i++) {
    try {
      const media = await axios.get(files[i], {
        responseType: "blob"
      });
      const flag = await puseDownload();
      if (flag) {
        ElMessage.info("共" + files.length + "个文件，正在下载第" + (i + 1) + "个，请耐心等待...");
        const fileURL = URL.createObjectURL(media.data);
        const link = document.createElement("a");
        link.href = fileURL;
        link.download = files[i].uri;
        link.target = "_blank"; // 可选，如果希望在新窗口中下载文件，请取消注释此行
        link.click();
        URL.revokeObjectURL(fileURL);
      }
    } catch (error) {
      ElMessage.error("第" + (i + 1) + "个文件下载失败！");
      console.log(error);
      continue;
    }
  }
  ElMessage.success("全部文件下载完成！");
};

/* 中断一下下载，防止不能连续下载 */
const puseDownload = async () => {
  return new Promise((resolve) => {
    const downloadTimer = setTimeout(() => {
      clearTimeout(downloadTimer);
      resolve(true);
    }, 500);
  });
};
</script>
<template>
  <div>
    <el-card class="box-card" shadow="never">
      <el-form :inline="true" :model="formInline" class="felx-nowrap">
        <el-form-item>
          <el-button type="primary" @click="handleAdd"
            ><el-icon> <Plus /> </el-icon> 添加文件
          </el-button>
        </el-form-item>
        <el-form-item>
          <el-input placeholder="请输入文件名进行搜索" v-model="formInline.file_name" clearable />
        </el-form-item>
        <el-form-item>
          <el-input type="number" v-model="formInline.file_size" placeholder="大于该大小(M)" clearable />
        </el-form-item>
        <el-form-item>
          <el-select v-model="formInline.file_type" filterable placeholder="请选择文件类型" clearable>
            <el-option v-for="item in fileTypes" :key="item.value" :label="item.name" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-select v-model="formInline.use_type" filterable placeholder="请选择使用场景" clearable>
            <el-option v-for="item in fileUseTypes" :key="item.value" :label="item.name" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-date-picker v-model="formInline.create_time" type="date" placeholder="该时间以前" />
        </el-form-item>
        <el-form-item>
          <el-button icon="Search" type="primary" @click="dataInit" circle />
        </el-form-item>
      </el-form>
      <el-table
        :data="tableData"
        stripe
        id="table-list"
        v-loading="loading"
        element-loading-text="Loading..."
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55" />
        <el-table-column prop="file_name" label="文件名" show-overflow-tooltip width="180" />
        <el-table-column label="图片预览">
          <template #default="scope">
            <el-image
              class="image-item"
              :src="BASE_URL + 'Thumbnail/' + scope.row.file_name"
              fit="cover"
              v-if="scope.row.file_type === 'image'"
              @click="handlePreview(scope.row.file_name)"
            />
          </template>
        </el-table-column>
        <el-table-column label="文件大小">
          <template #default="scope">
            <div>{{ (scope.row.file_size / 1000000).toFixed(2) }}M</div>
          </template>
        </el-table-column>
        <el-table-column label="文件类型">
          <template #default="scope">
            <el-tag type="primary">{{ fileTypes.find((e) => e.value === scope.row.file_type).name }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="使用场景">
          <template #default="scope">
            <el-tag type="success">{{ fileUseTypes.find((e) => e.value === scope.row.use_type).name }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="upload_uid" label="上传者uid" width="80" />
        <el-table-column label="创建时间">
          <template #default="scope">
            {{ dayjs(scope.row.create_time).format("YYYY-MM-DD HH:mm") }}
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template #default="scope">
            <el-popconfirm title="确认删除?" @confirm="handleDelete([scope.row.id])">
              <template #reference>
                <el-button type="danger" icon="Delete" circle />
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <div class="m-t felx-nowrap">
        <div v-if="formInline.isPaging">
          <el-pagination
            v-model:current-page="currentPage"
            v-model:page-size="pageSize"
            :page-sizes="[20, 100, 200, 300, 400]"
            layout="total, sizes, prev, pager, next, jumper"
            :total="total"
            background
            @size-change="dataInit"
            @current-change="dataInit"
          />
        </div>
        <div class="m-l">
          <el-select v-model="formInline.isPaging" placeholder="是否分页">
            <el-option label="分页" :value="1" />
            <el-option label="不分页" :value="0" />
          </el-select>
        </div>
        <div class="m-l" v-if="selectionIds.length > 0">
          <el-button type="primary" icon="Download" @click="downloadAllFile(selectionFiles)">批量下载 </el-button>
        </div>
        <div class="m-l" v-if="selectionIds.length > 0">
          <el-button type="danger" icon="Delete" @click="handleDelete(selectionIds)">批量删除 </el-button>
        </div>
      </div>
    </el-card>

    <el-dialog v-model="dialogFormVisible" title="上传文件" width="25%">
      <el-form :model="dialogForm" label-width="auto">
        <el-form-item label="文件类型" required>
          <el-select v-model="dialogForm.file_type" filterable placeholder="请选择文件类型" clearable>
            <el-option v-for="item in fileTypes" :key="item.value" :label="item.name" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="使用场景" required>
          <el-select v-model="dialogForm.use_type" filterable placeholder="请选择使用场景" clearable>
            <el-option v-for="item in fileUseTypes" :key="item.value" :label="item.name" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="选择文件" required v-if="showUpload(dialogForm)">
          <el-upload v-model:file-list="fileList" class="upload-demo" action="#" :auto-upload="false" multiple>
            <el-button type="primary"
              ><el-icon> <Plus /> </el-icon> 选择文件
            </el-button>
          </el-upload>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogFormVisible = false">取消</el-button>
          <el-button type="primary" @click="submitForm(dialogForm)"> 开始上传 </el-button>
        </div>
      </template>
    </el-dialog>
    <el-dialog v-model="progressVisible" title="上传进度" width="30%" draggable :close-on-click-modal="false">
      <div>共{{ fileList.length }}个文件，当前上传第{{ nowUploadcount }}个文件</div>
      <div>{{ uploadSpeed }}Mb/s</div>
      <div class="m-t"><el-progress :text-inside="true" :stroke-width="26" :percentage="uploaProgress" /></div>
    </el-dialog>
    <el-dialog v-model="imageVisible" style="background-color: transparent; box-shadow: none">
      <div class="image-wrap"><el-image :src="viewedImage" fit="cover" /></div>
    </el-dialog>
  </div>
</template>

<style lang="scss" scoped>
.image-item {
  width: 50px;
  height: 50px;
  border-radius: 4px;
}
.image-wrap {
  width: 100%;
  height: 100vh;
  display: flex;
  justify-content: center;
}
</style>
